﻿using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Sonce.Editor.Data;

namespace Sonce.Editor.Tools
{
    public class NodeTool : IEditorTool
    {
        #region Members
        private NodeStyles nodeStyle = NodeStyles.Default;
        #endregion

        #region Constructor
        public NodeTool()
        {
        }
        #endregion

        #region Properties
        public NodeStyles NodeStyle
        {
            get
            {
                return this.nodeStyle;
            }
            set
            {
                this.nodeStyle = value;
            }
        }
        #endregion

        #region IEditorTool Members
        public Editor Editor
        {
            get;
            set;
        }

        public bool KeyDown(Key key)
        {
            return false;
        }

        public bool KeyUp(Key key)
        {
            return false;
        }

        public bool MouseDown(Point position)
        {
            DrawNode(this.Editor.LayerPreview, position, this.nodeStyle);
            return true;
        }

        public bool MouseUp(Point position)
        {
            this.Editor.LayerPreview.Clear();
            DrawNode(this.Editor.LayerWorking, position, this.nodeStyle);
            return true;
        }

        public bool MouseMove(Point position, bool isMouseDown)
        {
            if (isMouseDown)
            {
                DrawNode(this.Editor.LayerPreview, position, this.nodeStyle);
                this.Editor.SelectionManager.HighlightTouchingLines(position);
            }
            return true;
        }

        public bool MouseEnter()
        {
            return false;
        }

        public bool MouseLeave()
        {
            return false;
        }

        public bool MouseWheel(int delta)
        {
            return false;
        }
        #endregion

        #region Draw methods
        public static FrameworkElement CreateNode(NodeStyles style, Brush brush)
        {
            Canvas canvas = new Canvas();
            canvas.Cursor = Cursors.Hand;
            canvas.Background = new SolidColorBrush(Colors.Transparent);
            //canvas.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e) { OnPick(new NodeEventArgs(this)); };
            //canvas.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e) { OnDrop(new NodeEventArgs(this)); };

            #region Render
            switch (style)
            {
                case NodeStyles.Square:
                    canvas.Width = 12;
                    canvas.Height = 12;

                    Rectangle rectangle = new Rectangle();
                    rectangle.Margin = new Thickness(3, 3, 0, 0);
                    rectangle.Width = 7;
                    rectangle.Height = 7;
                    rectangle.Fill = new SolidColorBrush(Colors.Transparent);
                    rectangle.Stroke = brush;
                    canvas.Children.Add(rectangle);

                    rectangle = new Rectangle();
                    rectangle.Margin = new Thickness(5, 5, 0, 0);
                    rectangle.Width = 3;
                    rectangle.Height = 3;
                    rectangle.Fill = brush;
                    rectangle.Stroke = brush;
                    canvas.Children.Add(rectangle);
                    break;

                default:
                case NodeStyles.Dot:
                    canvas.Width = 8;
                    canvas.Height = 8;

                    Ellipse ellipse = new Ellipse();
                    ellipse.Margin = new Thickness(1, 1, 0, 0);
                    ellipse.Width = 6;
                    ellipse.Height = 6;
                    ellipse.Stroke = brush;
                    ellipse.Fill = brush;
                    canvas.Children.Add(ellipse);
                    break;
            }
            #endregion

            return canvas;
        }

        /// <summary>
        /// Overloaded. Draw a node at the specified location.
        /// </summary>
        /// <param name="position">Location of the visual object.</param>
        /// <returns>Returns the drawn visual object for futher customization.</returns>
        public FrameworkElement DrawNode(Layer layer, Point position)
        {
            return DrawNode(layer, position, NodeStyles.Default);
        }

        /// <summary>
        /// Draw a node at the specified location.
        /// </summary>
        /// <param name="position">Location of the visual object.</param>
        /// <param name="style">Predefined style of the node.</param>
        /// <returns>Returns the drawn visual object for further customization.</returns>
        public FrameworkElement DrawNode(Layer layer, Point position, NodeStyles style)
        {
            FrameworkElement visual = CreateNode(style, layer.StrokeBrush);
            visual.Margin = new Thickness(position.X - visual.Width / 2, position.Y - visual.Height / 2, 0, 0); //Visual position, top-left edge of node
            visual.HorizontalAlignment = HorizontalAlignment.Left;
            visual.VerticalAlignment = VerticalAlignment.Top;
            layer.Draw(visual);

            //If the layer is permanent (not floating)
            if (layer == this.Editor.LayerWorking) //TODO: Or it's sub layer
            {
                //Insert node into local database
                EditorDataContext db = new EditorDataContext();
                Node node = new Node();
                node.DocumentId = this.Editor.CurrentDocumentId;
                //node.Label = item.Label;
                node.X = position.X;
                node.Y = position.Y;
                db.Nodes.Add(node);

                //Indicates that this is a fixed visual object (cannot be ungrouped or exploded)
                NodeTag tag = new NodeTag();
                tag.Position = position; //Logical position, center of node
                tag.Id = node.Id;
                visual.Tag = tag;
            }

            return visual;
        }
        #endregion
    }
}
